package cn.mumzone.pos.ui.fragment;

import android.app.Dialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.InputType;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.github.jdsjlzx.recyclerview.LRecyclerView;
import com.github.jdsjlzx.recyclerview.LRecyclerViewAdapter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;
import cn.mumzone.basic.adapter.TextWatcherAdapter;
import cn.mumzone.basic.base.BaseFragment;
import cn.mumzone.basic.dialog.AlertDialog;
import cn.mumzone.basic.loading.button.LoadingButton;
import cn.mumzone.basic.util.AppDateUtil;
import cn.mumzone.basic.util.EditTextUtil;
import cn.mumzone.basic.util.ListUtil;
import cn.mumzone.basic.util.NetUtil;
import cn.mumzone.basic.util.PosToast;
import cn.mumzone.basic.util.RxBus;
import cn.mumzone.basic.util.StringUtils;
import cn.mumzone.basic.util.log.Elog;
import cn.mumzone.pos.R;
import cn.mumzone.pos.dialog.PosAlertDialog;
import cn.mumzone.pos.dialog.PosDialog;
import cn.mumzone.pos.event.MoreViewChangeEvent;
import cn.mumzone.pos.model.AddInInventoryEntity;
import cn.mumzone.pos.model.AddOutInventoryEntity;
import cn.mumzone.pos.model.RepoGoodsEntity;
import cn.mumzone.pos.model.RepoListGoodsEntity;
import cn.mumzone.pos.model.RepositoryEntity;
import cn.mumzone.pos.presenter.StockOutPresenter;
import cn.mumzone.pos.presenter.contract.StockOutContract;
import cn.mumzone.pos.ui.activity.ACT_SearchStockInOrOut;
import cn.mumzone.pos.ui.activity.ACT_SearchStockInOrOutForScan;
import cn.mumzone.pos.ui.adapter.ADA_SelectRepository;
import cn.mumzone.pos.ui.adapter.ADA_StockInAndOut;
import cn.mumzone.pos.util.GoodsUtil;

/**
 * Created by JoeLjt on 2019/9/26.
 * Email: lijiateng1219@gmail.com
 * Description:
 */

public class FRA_StockOut extends BaseFragment<StockOutPresenter> implements StockOutContract.View {

    public static final int STOCK_TYPE_OUT = 1000;

    @BindView(R.id.et_scan)
    EditText etScan;
    @BindView(R.id.ll_repository)
    LinearLayout llRepository;
    @BindView(R.id.tv_repository)
    TextView tvRepository;
    @BindView(R.id.ll_empty_cart)
    LinearLayout llDefault;
    @BindView(R.id.rv_cart_goods)
    LRecyclerView rvCart;
    @BindView(R.id.rg_type)
    RadioGroup rgType;
    @BindView(R.id.tv_bill_date)
    TextView tvBillDate;
    @BindView(R.id.et_out_stock_remark)
    EditText etRemark;
    @BindView(R.id.tv_clear_selected)
    TextView tvClear;
    @BindView(R.id.tv_add_stock)
    TextView tvAddStock;
    @BindView(R.id.btn_generate)
    LoadingButton btnGenerate;

    private LinkedList<RepoListGoodsEntity> goodsList = new LinkedList<>();

    private PosAlertDialog deleteConfirmDialog;
    private PosAlertDialog deleteBatchConfirmDialog;
    private PosAlertDialog clearConfirmDialog;

    private AlertDialog mSelectRepoDialog;
    private ADA_SelectRepository mRepoAdapter;

    private LRecyclerViewAdapter mGoodsViewAdapter;
    private ADA_StockInAndOut mStockCartAdapter;

    private boolean isScanExecuted = false;

    private RepositoryEntity mSelectedRepo;

    private String scanCode;

    @Override
    protected void onUserVisible() {
        etScan.requestFocus();
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            mPresenter.loadRepositoryList();
            etScan.requestFocus();
        }
    }

    @Override
    protected void initEventAndData() {

        initViews();

        initSelectRepoDialog();

        mPresenter.loadRepositoryList();

    }

    private void initViews() {

        updateStockSearchResultUI(true);
        tvBillDate.setText(AppDateUtil.getTimeStamp(System.currentTimeMillis(), AppDateUtil.YYYY_MM_DD));

        rvCart.setLayoutManager(new LinearLayoutManager(mContext));
        mStockCartAdapter = new ADA_StockInAndOut(mContext, STOCK_TYPE_OUT, true);
        mStockCartAdapter.setOnItemDeleteClickedListener(new ADA_StockInAndOut.OnItemDeleteClickedListener() {
            @Override
            public void OnClicked(int position, RepoListGoodsEntity repoGoodsEntity) {
                showDeleteConfirmDialog(position);
            }
        });

        mStockCartAdapter.setOnBatchDeletedListener(new ADA_StockInAndOut.OnBatchDeleteClickedListener() {
            @Override
            public void onBatchDeleted(RepoListGoodsEntity currEntity, RepoGoodsEntity currBatch) {
                // 点击某个批次的减号时
                // 1. 如果当前是唯一有数量的批次，那减掉此批次的同时也会移除此商品
                // 2. 如果不是唯一批次，就把当前批次的已选数量置为 0 即可
                showDeleteBatchConfirmDialog(isOnlyBatch(currEntity.getGoodsBatch()), currEntity, currBatch);
            }
        });

        mStockCartAdapter.setOnAmountChangeListener(new ADA_StockInAndOut.OnAmountChangeListener() {
            @Override
            public void onAmountChanged(int count, int tag, RepoListGoodsEntity currEntity) {
                if (count > 0) {
                    return;
                }

                if (tag == -1) {
                    // 如果是单批次商品，直接提示删除商品
                    showDeleteBatchConfirmDialog(true, currEntity, null);
                } else {
                    // 如果是多批次商品，那需要确定是哪个批次减到了零
                    showDeleteBatchConfirmDialog(false, currEntity, currEntity.getGoodsBatch().get(tag));
                }

            }
        });

        mGoodsViewAdapter = new LRecyclerViewAdapter(mStockCartAdapter);
        rvCart.setAdapter(mGoodsViewAdapter);
        rvCart.setPullRefreshEnabled(false);
        rvCart.setLoadMoreEnabled(false);

        initScanCodeRelated();
    }

    /**
     * 初始化扫码工作
     */
    private void initScanCodeRelated() {
        etScan.setInputType(InputType.TYPE_NULL);
        EditTextUtil.hideSoftInputMethod(mContext, etScan);
        GoodsUtil.initScanForGoodsSold(mContext, etScan, etRemark, new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                String code = v.getText().toString().trim();
                if (actionId == KeyEvent.ACTION_DOWN && !TextUtils.isEmpty(code)) {

                    if (isHidden()){
                        return true;
                    }

                    if (mSelectedRepo == null || TextUtils.isEmpty(mSelectedRepo.getId())) {
                        PosToast.INSTANCE.makeShortToast(mContext, "请先选择仓库");
                        scanCode = null;
                        isScanExecuted = false;
                        return true;
                    }

                    scanCode = code;

                    if (!NetUtil.isNetworkAvailable(mContext)) {
                        PosToast.INSTANCE.makeShortToast(mContext, "网络不给力，请稍候再试");
                        return true;
                    }

                    if (!isScanExecuted) {
                        mPresenter.loadRepoGoodsById(mSelectedRepo != null ? StringUtils.get(mSelectedRepo.getId()) : "", scanCode);
                        rvCart.setNoMore(false);
                    }
                    isScanExecuted = true;
                    etScan.setText("");
                }
                return true;
            }
        }, new TextWatcherAdapter() {
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }
        });
    }

    /**
     * 判断当前商品是不是只有一个有选中数量的批次
     * <p>
     * 看对应的商品其他批次有没有 selectCount
     */
    private boolean isOnlyBatch(List<RepoGoodsEntity> localBatch) {
        int batchNum = 0;
        for (RepoGoodsEntity batchBean : localBatch) {
            if (batchBean.getSelectedCount() > 0) {
                batchNum++;
            }
        }
        return batchNum == 1;
    }

    private void updateStockSearchResultUI(boolean showDefault) {
        llDefault.setVisibility(showDefault ? View.VISIBLE : View.GONE);
        rvCart.setVisibility(!showDefault ? View.VISIBLE : View.GONE);
        tvClear.setEnabled(!showDefault);
        btnGenerate.setEnable(!showDefault);
    }

    @Override
    protected int getLayout() {
        return R.layout.fra_stock_out;
    }

    @OnClick({R.id.iv_back, R.id.ll_repository, R.id.tv_clear_selected,
            R.id.tv_add_stock, R.id.btn_generate, R.id.ll_remark})
    void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.iv_back:
                RxBus.getDefault().post(new MoreViewChangeEvent(MoreViewChangeEvent.MORE_VIE_HOME));
                break;
            case R.id.ll_repository:
                showDialog(mSelectRepoDialog);
                break;
            case R.id.tv_clear_selected:
                showClearConfirmDialog();
                break;
            case R.id.tv_add_stock:
                if (mSelectedRepo == null || TextUtils.isEmpty(mSelectedRepo.getId())) {
                    PosToast.INSTANCE.makeShortToast(mContext, "请先选择仓库");
                    return;
                }
                ACT_SearchStockInOrOut.startActFromStockOut(getActivity(), mSelectedRepo, goodsList);
                break;
            case R.id.btn_generate:
                doGenerateBill();
                break;
            case R.id.ll_remark:
                showRemarkDialog();
                break;
        }
    }


    private void showRemarkDialog() {
        final AlertDialog remarkDialog = new PosDialog.PosBuilder(mContext)
                .setRealDialogContent(R.layout.dialog_stock_remark)
                .setDialogTitle("备注")
                .setWidthAndHeight(438, -2)
                .show();

        final TextView tvLimit = remarkDialog.getView(R.id.tv_limit);
        final EditText view = remarkDialog.getView(R.id.et_stock_remark);
        view.setText(etRemark.getText().toString());
        view.requestFocus();
        view.addTextChangedListener(new TextWatcherAdapter() {
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                tvLimit.setText(view.getText().toString().length() + "/200");
            }
        });

        View lbConfirm = remarkDialog.getView(R.id.lb_confirm);
        lbConfirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                etRemark.setText(view.getText().toString());
                remarkDialog.dismiss();
            }
        });

    }

    /**
     * @param isDeleteGoods 是不是要删除商品
     *                      1. 单批次商品，移除商品时
     *                      2. 多批次，但是只有一个批次，移除批次时
     * @param currEntity
     * @param currBatch
     */
    private void showDeleteBatchConfirmDialog(final boolean isDeleteGoods,
                                              final RepoListGoodsEntity currEntity,
                                              final RepoGoodsEntity currBatch) {
        deleteBatchConfirmDialog = new PosAlertDialog.Builder(mContext)
                .setRemindText(isDeleteGoods ? String.format("确认要删除商品【%s】吗？", currEntity.getGoodsName())
                        : String.format("确认要删除批次【%s】吗？", currBatch.getGoodsBatchNumber()))
                .setPrimaryText("确认删除")
                .setPrimaryLoadingText("删除中")
                .setUseLoadingButton(true)
                .setOnConfirmClickListener(new PosAlertDialog.OnConfirmClickListener() {
                    @Override
                    public void onConfirmClick(View view, Dialog dialog) {

                        if (currBatch != null) {
                            currBatch.setSelectedCount(0);
                        }

                        if (isDeleteGoods) {
                            currEntity.setSelectedCount(0);
                        }

                        updateLocalCartListSafely(goodsList, currEntity);
                        mStockCartAdapter.update(goodsList, true);
                        mGoodsViewAdapter.notifyDataSetChanged();
                        updateStockSearchResultUI(ListUtil.isListEmpty(goodsList));
                        deleteBatchConfirmDialog.dismiss();
                    }
                })
                .setOnCancelClickListener(new PosAlertDialog.OnCancelClickListener() {
                    @Override
                    public void onCancelClick(View view, Dialog dialog) {

                        if (currBatch != null) {
                            currBatch.setSelectedCount(1);
                        }

                        if (isDeleteGoods) {
                            currEntity.setSelectedCount(1);
                        }

                        updateLocalCartListSafely(goodsList, currEntity);
                        mStockCartAdapter.update(goodsList, true);
                        mGoodsViewAdapter.notifyDataSetChanged();
                        updateStockSearchResultUI(ListUtil.isListEmpty(goodsList));
                        deleteBatchConfirmDialog.dismiss();
                    }
                })
                .build();
        deleteBatchConfirmDialog.show();
    }

    private void showDeleteConfirmDialog(final int position) {
        String goodsName = mStockCartAdapter.getDataList().get(position).getGoodsName();
        deleteConfirmDialog = new PosAlertDialog.Builder(mContext)
                .setRemindText(String.format("确认要删除商品【%s】吗？", goodsName))
                .setPrimaryText("确认删除")
                .setPrimaryLoadingText("删除中")
                .setUseLoadingButton(true)
                .setOnConfirmClickListener(new PosAlertDialog.OnConfirmClickListener() {
                    @Override
                    public void onConfirmClick(View view, Dialog dialog) {
                        mStockCartAdapter.getDataList().remove(position);
                        mStockCartAdapter.notifyDataSetChanged();

                        // 从 goodsList 中删除
                        goodsList.remove(position);

                        deleteConfirmDialog.dismiss();
                        updateStockSearchResultUI(ListUtil.isListEmpty(mStockCartAdapter.getDataList()));
                        PosToast.INSTANCE.makeCheckMarkToast(mContext, "已删除");
                    }
                }).build();
        deleteConfirmDialog.show();
    }

    private void showClearConfirmDialog() {
        clearConfirmDialog = new PosAlertDialog.Builder(mContext)
                .setRemindText("确认要删除所有已选择的商品吗？")
                .setPrimaryText("全部删除")
                .setPrimaryLoadingText("删除中")
                .setUseLoadingButton(true)
                .setOnConfirmClickListener(new PosAlertDialog.OnConfirmClickListener() {
                    @Override
                    public void onConfirmClick(View view, Dialog dialog) {
                        mStockCartAdapter.clear();
                        goodsList.clear();
                        tvClear.setEnabled(false);
                        btnGenerate.setEnable(false);
                        updateStockSearchResultUI(true);
                        clearConfirmDialog.dismiss();
                        PosToast.INSTANCE.makeCheckMarkToast(mContext, "已删除");
                    }
                }).build();
        clearConfirmDialog.show();
    }

    /**
     * 发起请求，生成出库单
     */
    private void doGenerateBill() {
        btnGenerate.startLoading("正在生成出库单");
        String repoId = mSelectedRepo.getId();
        String repoType = getRepoTypeAndPattern(((RadioButton) (
                rgType.findViewById(rgType.getCheckedRadioButtonId()))).getText().toString());
        String goodsJson = getGoodJson(mStockCartAdapter.getDataList());
        Log.e("doGenerateBill: ", mStockCartAdapter.getDataList().size() + "");
        mPresenter.generateOutBill(repoId,
                repoType,
                StringUtils.get(getGoodsTotalNum()),
                StringUtils.get(getGoodsTotalPrice()),
                etRemark.getText().toString(),
                goodsJson);

    }

    private String getGoodJson(List<RepoListGoodsEntity> dataList) {
        ArrayList<AddOutInventoryEntity> arrayList = new ArrayList<>();
        for (RepoListGoodsEntity entity : dataList) {

            AddOutInventoryEntity inventoryEntity;

            if (entity.getIsBatch() == RepoListGoodsEntity.BATCH_OFF) {

                inventoryEntity = new AddOutInventoryEntity();
                RepoGoodsEntity batchInfo = entity.getGoodsBatch().get(0);
                inventoryEntity.setGoodsNum(String.valueOf(entity.getSelectedCount()));

                // 只有手动添加批次的时候，entity.getInStockPrice() 才有值，平时都是用里边的
                inventoryEntity.setGoodsPrice(String.valueOf(batchInfo.getGoodsPrice()));
                inventoryEntity.setGoodsBatchNumber(batchInfo.getGoodsBatchNumber());
                inventoryEntity.setDateInProduced(batchInfo.getDateInProduced());

                inventoryEntity.setGoodsId(entity.getGoodsId());
                inventoryEntity.setGoodsName(entity.getGoodsName());
                inventoryEntity.setGoodsUnit(batchInfo.getGoodsUnit());
                inventoryEntity.setGoodsCode(batchInfo.getGoodsCode());
                inventoryEntity.setGoodsSpec(ListUtil.isListEmpty(entity.getParameter()) ? "" : JSON.toJSONString(entity.getParameter()));
                inventoryEntity.setBarCode(batchInfo.getBarCode());

                arrayList.add(inventoryEntity);
                continue;
            }

            List<RepoGoodsEntity> goodsBatch = entity.getGoodsBatch();
            for (int i = 0; i < goodsBatch.size(); i++) {

                RepoGoodsEntity zeroBatch = goodsBatch.get(0);
                RepoGoodsEntity batchInfo = goodsBatch.get(i);

                if (batchInfo.getSelectedCount() > 0) {
                    inventoryEntity = new AddOutInventoryEntity();

                    inventoryEntity.setGoodsBatchNumber(batchInfo.getGoodsBatchNumber());
                    inventoryEntity.setGoodsNum(String.valueOf(batchInfo.getSelectedCount()));
                    inventoryEntity.setDateInProduced(batchInfo.getDateInProduced());
                    inventoryEntity.setGoodsPrice(String.valueOf(batchInfo.getGoodsPrice()));

                    inventoryEntity.setGoodsId(entity.getGoodsId());
                    inventoryEntity.setGoodsName(entity.getGoodsName());
                    inventoryEntity.setGoodsUnit(zeroBatch.getGoodsUnit());
                    inventoryEntity.setGoodsCode(zeroBatch.getGoodsCode());
                    inventoryEntity.setGoodsSpec(ListUtil.isListEmpty(entity.getParameter()) ? "" : JSON.toJSONString(entity.getParameter()));
                    inventoryEntity.setBarCode(zeroBatch.getBarCode());

                    arrayList.add(inventoryEntity);
                }
            }

        }
        Log.e("getGoodJson: ", JSON.toJSONString(arrayList) + dataList.get(0).getGoodsName()  /*+ arrayList.get(0).getGoodsName()*/);
        return JSON.toJSONString(arrayList, SerializerFeature.DisableCircularReferenceDetect);
    }


    private int getGoodsTotalNum() {
        int totalNum = 0;
        for (RepoListGoodsEntity localBean : goodsList) {
            int num = 0;
            if (localBean.getIsBatch() == RepoListGoodsEntity.BATCH_OFF) {
                num = localBean.getSelectedCount();
            } else {
                for (RepoGoodsEntity repoGoodsEntity : localBean.getGoodsBatch()) {
                    num += repoGoodsEntity.getSelectedCount();
                }
            }
            totalNum += num;
        }
        return totalNum;
    }

    private double getGoodsTotalPrice() {
        double totalPrice = 0.0;
        for (RepoListGoodsEntity localBean : goodsList) {
            double price = 0;
            if (localBean.getIsBatch() == RepoListGoodsEntity.BATCH_OFF) {
                price = localBean.getSelectedCount()
                        * Double.parseDouble(localBean.getGoodsBatch().get(0).getGoodsPrice());
            } else {
                for (RepoGoodsEntity repoGoodsEntity : localBean.getGoodsBatch()) {
                    int batchCount = repoGoodsEntity.getSelectedCount();
                    double batchPrice = Double.parseDouble(repoGoodsEntity.getGoodsPrice());
                    price += (batchCount * batchPrice);
                }
            }
            totalPrice += price;
        }
        return totalPrice;
    }

    private String getRepoTypeAndPattern(String text) {
        if ("盘亏".equals(text)) {
            return "2";
        } else if ("报损".equals(text)) {
            return "5";
        } else {
            return "0";
        }
    }

    private void updateRepoTypeCheckStatus(int checkId) {

        // 盘点类型
        for (int i = 0; i < rgType.getChildCount(); i++) {
            RadioButton button = (RadioButton) rgType.getChildAt(i);
            button.setChecked(checkId == button.getId());
        }

    }

    private void initSelectRepoDialog() {
        mSelectRepoDialog = new PosDialog.PosBuilder(mContext, PosDialog.DIALOG_BLACK_TITLE)
                .setRealDialogContent(R.layout.dialog_select_repotory)
                .setUseRadiusBg(false)
                .setDialogTitle("选择仓库")
                .setWidthAndHeight(522, WindowManager.LayoutParams.MATCH_PARENT)
                .fromRight(true)
                .create();
        RecyclerView rvRepository = mSelectRepoDialog.getView(R.id.rv_repository);
        rvRepository.setLayoutManager(new LinearLayoutManager(mContext));
        mRepoAdapter = new ADA_SelectRepository(mContext);
        mRepoAdapter.setOnItemClickedListener(new ADA_SelectRepository.OnItemClickedListener() {
            @Override
            public void onItemClicked(int position) {

                mSelectedRepo = mRepoAdapter.getDataList().get(position);
                tvRepository.setText(mSelectedRepo.getRepositoryName());
                closeDialog(mSelectRepoDialog);

                // 重新选择仓库后要清空原数据
                mStockCartAdapter.clear();
            }
        });
        rvRepository.setAdapter(mRepoAdapter);
        rvRepository.setHasFixedSize(true);
    }

    @Override
    public void showRepositoryList(List<RepositoryEntity> repositoryList) {
        if (!ListUtil.isListEmpty(repositoryList)) {
            mSelectRepoDialog.toggleShowEmpty(false, R.id.rv_repository);
            mSelectedRepo = repositoryList.get(0);
            tvRepository.setText(repositoryList.get(0).getRepositoryName());
            mRepoAdapter.update(repositoryList, true);
        } else {
            mSelectRepoDialog.toggleShowEmpty(true, R.id.rv_repository, R.mipmap.ic_bill_empty, "暂未创建仓库");
        }
        llRepository.setClickable(!ListUtil.isListEmpty(repositoryList));
//        tvAddStock.setClickable(!ListUtil.isListEmpty(repositoryList));
    }

    @Override
    public void showScanGoodsDialog(List<RepoListGoodsEntity> scanList) {

        if (mSelectedRepo == null || TextUtils.isEmpty(mSelectedRepo.getId())) {
            PosToast.INSTANCE.makeShortToast(mContext, "请先选择仓库");
            scanCode = null;
            isScanExecuted = false;
            return;
        }

        ACT_SearchStockInOrOutForScan.startActForScanFromStockOut(getActivity(), mSelectedRepo, scanCode, scanList, goodsList);
        scanCode = null;
        isScanExecuted = false;
    }

    @Override
    public void onBillGenerated() {
        btnGenerate.stopLoading("生成出库单");
        PosToast.INSTANCE.makeCheckMarkToast(mContext, "已生成");
        RxBus.getDefault().post(new MoreViewChangeEvent(MoreViewChangeEvent.MORE_VIE_HOME));
//        clearOutStockData();
    }

    @Override
    public void onBackPressed(int type) {
        if (type == MoreViewChangeEvent.MORE_VIE_HOME)
            clearOutStockData();
    }

    private void clearOutStockData() {

        mStockCartAdapter.clear();
        goodsList.clear();

        etRemark.setText("");

        mGoodsViewAdapter = new LRecyclerViewAdapter(mStockCartAdapter);
        rvCart.setAdapter(mGoodsViewAdapter);

        tvClear.setEnabled(false);
        btnGenerate.setEnable(false);

        updateStockSearchResultUI(true);

        rgType.check(R.id.rb_others);

    }

    @Override
    public void showError(String msg) {
        super.showError(msg);
        btnGenerate.stopLoading("生成出库单");
        isScanExecuted = false;
    }

    @Override
    public void onGoodsAdded(List<RepoListGoodsEntity> entityList) {

        if (isHidden()) {
            return;
        }

        // v2.3，取消「搜索页与结果页实时交互」，添加确认按钮
        for (RepoListGoodsEntity entity : entityList) {
            updateLocalCartListSafely(goodsList, entity);
        }
        updateStockSearchResultUI(ListUtil.isListEmpty(goodsList));
        mStockCartAdapter.update(goodsList, true);
        mGoodsViewAdapter.notifyDataSetChanged();

    }

    /**
     * 更新本地购物车列表
     */
    public void updateLocalCartListSafely(LinkedList<RepoListGoodsEntity> localList, RepoListGoodsEntity recentAdd) {

        boolean isUpdate = false;
        Iterator<RepoListGoodsEntity> localIterator = localList.iterator();
        while (localIterator.hasNext()) {
            RepoListGoodsEntity localBean = localIterator.next();

            // 匹配同商品
            if (localBean.getGoodsId().equals(recentAdd.getGoodsId())) {
                if (localBean.getIsBatch() == RepoListGoodsEntity.BATCH_OFF) {
                    // 如果是单批次商品，直接更新数量
                    localBean.setSelectedCount(recentAdd.getSelectedCount());
                    // 如果数量减到 0，就移除该条数据
                    if (localBean.getSelectedCount() == 0) {
                        localIterator.remove();
                    }
                } else {
                    // 多批次商品，匹配批次号
                    List<RepoGoodsEntity> localBatch = localBean.getGoodsBatch();
                    List<RepoGoodsEntity> recentAddBatch = recentAdd.getGoodsBatch();

                    boolean isAllBatchZero = true;
                    for (RepoGoodsEntity lBatch : localBatch) {
                        for (RepoGoodsEntity rBatch : recentAddBatch) {
                            if (lBatch.getGoodsBatchNumber().equals(rBatch.getGoodsBatchNumber())) {
                                lBatch.setSelectedCount(rBatch.getSelectedCount());
                                break;
                            }
                        }

                        // 如果操作完以后，所有批次都为 0，那就移除这条数据
                        if (lBatch.getSelectedCount() > 0) {
                            isAllBatchZero = false;
                        }
                    }

                    if (isAllBatchZero) {
                        localIterator.remove();
                    }
                }
                isUpdate = true;
            }
        }

        // 不是更新数据，则说明是要插入的新数据
        if (!isUpdate) {
            boolean isNumValid = false;
            if (recentAdd.getIsBatch() == RepoListGoodsEntity.BATCH_ON) {
                for (RepoGoodsEntity batchInfo : recentAdd.getGoodsBatch()) {
                    if (batchInfo.getSelectedCount() > 0) {
                        isNumValid = true;
                        break;
                    }
                }
            } else {
                isNumValid = recentAdd.getSelectedCount() > 0;
            }

            if (isNumValid) {
                localList.addFirst(recentAdd);
            }
        }

    }

}
